package com.parleys.android.client.io;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;

import org.json.JSONArray;
import org.json.JSONException;

import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;

import com.parleys.android.client.util.Sets;

public abstract class JSONHandler {

	private final String mAuthority;

	public JSONHandler(String mAuthority) {
		this.mAuthority = mAuthority;
	}
	
	public void parseAndApply(JSONArray json, ContentResolver resolver) throws HandlerException {
		try {
			final ArrayList<ContentProviderOperation> batch = parse(json, resolver);
			ContentProviderResult [] result = resolver.applyBatch(mAuthority, batch);
			notify(result, resolver);
		} catch (JSONException e) {
			throw new HandlerException("Problem parsing JSON response", e);
		} catch (RemoteException e) {
			throw new RuntimeException("Problem applying batch operation", e);
		} catch (OperationApplicationException e) {
			throw new RuntimeException("Problem applying batch operation", e);
		}
	}
	
	public abstract ArrayList<ContentProviderOperation> parse(JSONArray json, ContentResolver resolver) throws JSONException;

	public void notify(ContentProviderResult[] result, ContentResolver resolver) throws JSONException {
		if (result != null && result.length > 0) {
			resolver.notifyChange(result[0].uri, null);
		}
	}

    protected static HashSet<Long> getLostIds(HashSet<Long> ids, Uri uri, String [] projection, int idColumnIndex, ContentResolver resolver) {
        final HashSet<Long> lostIds = Sets.newHashSet();
        
        final Cursor cursor = resolver.query(uri, projection, null, null, null);
        try {
        	while (cursor.moveToNext()) {
        		final Long id = cursor.getLong(idColumnIndex);
        		if (!ids.contains(id)) {
        			lostIds.add(id);
        		}
        	}
        } finally {
            cursor.close();
        }
        
        return lostIds;
    }
    
    protected static boolean isEmptyThumbnail(String thumbnailUrl) {
    	return "thumb.png".equals(thumbnailUrl) || "null".equals(thumbnailUrl);
    }

    public static class HandlerException extends IOException {
        public HandlerException(String message) {
            super(message);
        }

        public HandlerException(String message, Throwable cause) {
            super(message);
            initCause(cause);
        }

        @Override
        public String toString() {
            if (getCause() != null) {
                return getLocalizedMessage() + ": " + getCause();
            } else {
                return getLocalizedMessage();
            }
        }
    }

}
